﻿#include "signaltransfer.h"

#include <QMediaPlayer>

#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
#include <QAudioOutput>
#else
#include <QMediaPlaylist>
#endif

SignalTransfer* SignalTransfer::m_pInstance = nullptr;

SignalTransfer *SignalTransfer::instance()
{
    if(!m_pInstance)
        m_pInstance = new SignalTransfer;

    return m_pInstance;
}

void SignalTransfer::closeInstance()
{
    if(m_pInstance)
        delete m_pInstance;
    m_pInstance = nullptr;
}

SignalTransfer::SignalTransfer(QObject *parent)
    : QObject{parent}
{
    // m_settings = new QSettings("ZDIT", "TETRIS", this);
    m_settings = new QSettings("config.ini", QSettings::IniFormat, this);

    m_blockSideLength = 40;

    //背景音乐
    m_backgroundplayer = new QMediaPlayer(this);

#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
    m_backgroundplayer->setSource(QUrl::fromEncoded("qrc:/audio/background.mp3"));
    m_backgroundplayer->setLoops(QMediaPlayer::Infinite);
    auto audioOutput = new QAudioOutput;
    m_backgroundplayer->setAudioOutput(audioOutput);
    audioOutput->setVolume(m_settings->value("MusicLevel", 3).toInt() * 10);
#else
    m_backgroundplayer->setVolume(m_settings->value("MusicLevel", 3).toInt() * 10);
    auto playlist = new QMediaPlaylist(this);
    playlist->addMedia(QUrl::fromEncoded("qrc:/audio/background.mp3"));
    playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    m_backgroundplayer->setPlaylist(playlist);
#endif


    m_soundList = new SoundList;
    m_soundList->freeze.setSource(QUrl::fromEncoded("qrc:/audio/freeze.wav"));
    m_soundList->gameover.setSource(QUrl::fromEncoded("qrc:/audio/gameover.wav"));
    m_soundList->down.setSource(QUrl::fromEncoded("qrc:/audio/down.wav"));
    m_soundList->remove.setSource(QUrl::fromEncoded("qrc:/audio/remove.wav"));
    m_soundList->success.setSource(QUrl::fromEncoded("qrc:/audio/success.wav"));
    m_soundList->kickfailure.setSource(QUrl::fromEncoded("qrc:/audio/kickfailure.wav"));
    m_soundList->kicksuccess.setSource(QUrl::fromEncoded("qrc:/audio/kicksuccess.wav"));
    m_soundList->setVolume(m_settings->value("SoundEffectLevel", 3).toInt() / 10.0);

    //初始化速度表
    m_speedTable[1] = 1.00000;
    m_speedTable[2] = 0.79300;
    m_speedTable[3] = 0.61780;
    m_speedTable[4] = 0.47273;
    m_speedTable[5] = 0.35520;
    m_speedTable[6] = 0.26200;
    m_speedTable[7] = 0.18968;
    m_speedTable[8] = 0.13473;
    m_speedTable[9] = 0.09388;
    m_speedTable[10] = 0.06415;
    m_speedTable[11] = 0.04298;
    m_speedTable[12] = 0.02822;
    m_speedTable[13] = 0.01815;
    m_speedTable[14] = 0.01144;
    m_speedTable[15] = 0.00706;
    m_speedTable[16] = 0.00426;
    m_speedTable[17] = 0.00252;
    m_speedTable[18] = 0.00146;
    m_speedTable[19] = 0.00082;
    m_speedTable[20] = 0.00046;

    //加载得分记录
    QList<QVariant> list = m_settings->value("standard_recored_list").toList();
    foreach (auto v, list) {
        Record c = qvariant_cast<Record>(v);
        m_standard_record_list.append(c);
    }
    std::sort(m_standard_record_list.begin(), m_standard_record_list.end(), &SignalTransfer::compareByScore);    //重新排序

    list = m_settings->value("pass_recored_list").toList();
    foreach (auto v, list) {
        Record c = qvariant_cast<Record>(v);
        m_pass_record_list.append(c);
    }
    std::sort(m_pass_record_list.begin(), m_pass_record_list.end(), &SignalTransfer::compareInPassMode);
}

SignalTransfer::~SignalTransfer()
{
    delete m_soundList;
}

SignalTransfer::SoundList *SignalTransfer::soundList() const
{
    return m_soundList;
}

QList<Record> SignalTransfer::pass_record_list() const
{
    return m_pass_record_list;
}

bool SignalTransfer::canRankInPassRecord(const Record &record)
{
    if (m_pass_record_list.count() < maxRecordNum) {
        return true;
    } else if (compareInPassMode(record, m_pass_record_list.last())){
        return true;
    } else {
        return false;
    }
}

/**
 * @brief   速度转成间隔
 * @details 速度数值源自https://tetris.fandom.com/wiki/Tetris_Worlds
 * @param   speed -- 速度值
 * @param   Second
 * @return  间隔的ms数
 */
int SignalTransfer::speedToInterval(int speed)
{
    if (speed > 0 && speed < 21) {
        return (int)(1000 * m_speedTable.value(speed));
    } else {
        return 0;
    }
}

QList<Record> SignalTransfer::standard_record_list() const
{
    return m_standard_record_list;
}

bool SignalTransfer::canRankInStandardRecord(int score)
{
    if (m_standard_record_list.count() < maxRecordNum) {
        return true;
    } else if (score > m_standard_record_list.last().score){
        return true;
    } else {
        return false;
    }
}

QMediaPlayer *SignalTransfer::backgroundplayer() const
{
    return m_backgroundplayer;
}

/**
 * @brief   插入标准模式得分榜
 * @details 插入并自动排序，最多保存maxRecordNum个记录
 */
void SignalTransfer::insertStandardModeRecord(const Record &r)
{
    m_standard_record_list.append(r);
    std::sort(m_standard_record_list.begin(), m_standard_record_list.end(), &SignalTransfer::compareByScore);
    while (m_standard_record_list.count() > maxRecordNum) {
        m_standard_record_list.removeLast();
    }

    //存入QSettings
    QVariantList list;
    foreach (auto s, m_standard_record_list) {
        auto v = QVariant::fromValue(s);
        list.append(v);
    }
    m_settings->setValue(tr("standard_recored_list"), list);
}

/**
 * @brief   插入闯关模式得分榜
 * @details 插入并自动排序，最多保存maxRecordNum个记录
 */
void SignalTransfer::insertPassModeRecord(const Record &r)
{
    m_pass_record_list.append(r);
    std::sort(m_pass_record_list.begin(), m_pass_record_list.end(), &SignalTransfer::compareInPassMode);
    while (m_pass_record_list.count() > maxRecordNum) {
        m_pass_record_list.removeLast();
    }

    //存入QSettings
    QVariantList list;
    foreach (auto s, m_pass_record_list) {
        auto v = QVariant::fromValue(s);
        list.append(v);
    }
    m_settings->setValue(tr("pass_recored_list"), list);
}

int SignalTransfer::blockSideLength() const
{
    return m_blockSideLength;
}

void SignalTransfer::setBlockSideLength(int newBlockSideLength)
{
    m_blockSideLength = newBlockSideLength;
}

void SignalTransfer::setBackgroundMusicEnable(bool flag)
{
    if (ST->settings()->value("MusicLevel", 3).toInt() > 0) {
        if (flag) {
            m_backgroundplayer->play();
        } else {
            m_backgroundplayer->stop();
        }
    } else {
        m_backgroundplayer->stop();
    }
}

void SignalTransfer::delay_ms(int ms)
{
    QEventLoop eventloop;
    QTimer::singleShot(ms, &eventloop, SLOT(quit()));
    eventloop.exec();
}

QSettings *SignalTransfer::settings() const
{
    return m_settings;
}
